%s NORM INQUOTE INCOMMENT

%{
#include <stdio.h>
#include "y.tab.h"

/*
 * This yacc/lex setup provides for a first pass of an SGML dtd.
 * It does the following things:
 *	removes all comments.
 *	does appropriate handling of entities
 * The input would be an html dtd files (such as html2.dtd)
 * and the output would just be a series of ELEMENT and ATTLIST lines.
 *
 * This does not work correctly for the html 3.0 dtd.  It has the following
 * problems:
 *	There are some wierd comment constructs in the dtd.
 *	There are some new SGML markups including NOTATION, USEMAP
 *	and SHORTREF that are not handled.
 *	Finally, the ATTLIST for STYLES is not parsed correctly.
 */
static int first_time = 1;
static char inquote;

/* For SGI lex */
#undef YYLMAX
#define YYLMAX 8 * 1024
/* #define DEBUG 10 */

%}

%%
%{
	if (first_time) {
	    BEGIN NORM;
	    first_time = 0;
	}
%}

<NORM>"<!"		{

#if (DEBUG > 9)
			   fprintf(stderr, "SGML: %s\n", yytext);
#endif
			    return (SGML);
			}

<NORM>"<!ELEMENT"	{

#if (DEBUG > 9)
			   fprintf(stderr, "ELESTART");
#endif
			    return (ELESTART);
			}

<NORM>"<!ATTLIST"	{

#if (DEBUG > 9)
			    fprintf(stderr, "ATTSTART\n");
#endif
			    return (ATTSTART);
			}
<NORM>"<!ENTITY"	{

#if (DEBUG > 9)
			    fprintf(stderr, "ENTSTART\n");
#endif
			    return (ENTSTART);
			}
<NORM>"<!["		{

#if (DEBUG > 9)
			    fprintf(stderr, "COND\n");
#endif
			    return (COND);
			}
<NORM>[<>%]|"]"|"["	{

#if (DEBUG > 9)
			    fprintf(stderr, "Char: %c\n", *yytext);
#endif
			    return (*yytext);
			}

<NORM>"--"(=*) {
  {
   int c;
   while((c = input())) {
      if(c == '-') {
      c = input();
      if(c == '-') {
        break;
      }
      }
    }
   }

#if (DEBUG > 9)
			    fprintf(stderr, "COMMENT\n");
#endif
			}

<NORM>%[a-zA-Z0-9.-]*;	{

#if (DEBUG > 9)
			    fprintf(stderr, "ENTITY: %s\n", yytext);
#endif
			    yylval.string = (char *)strdup(&yytext[1]);
			    yylval.string[strlen(yylval.string) - 1] = NULL;
			    return (ENTITY);
			}

<NORM>%[a-zA-Z0-9.-]*	{

#if (DEBUG > 9)
			    fprintf(stderr, "ENTITY: %s\n", yytext);
#endif
			    yylval.string = (char *)strdup(&yytext[1]);
			    return (ENTITY);
			}

<NORM>([^ \n\t\r%<>"'\]\[]|"<"[^!])*     {

#if (DEBUG > 9)
			    fprintf(stderr, "WORD: %s\n", yytext);
#endif
			    /* Simple word */
			    yylval.string = (char *)strdup(yytext);
			    return (WORD);
			}

<NORM>["']		{
			    BEGIN INQUOTE;
			    inquote = *yytext;
#if (DEBUG > 9)
#endif
			    return (QUOTE);
			}

<INQUOTE>["']		{
			    if (inquote == *yytext) {
				BEGIN NORM;
				return (QUOTE);
			    }
			    else {
				yylval.string = (char *)strdup(yytext);
				return (WORD);
			    }
			}

<INQUOTE>[^%"']+	{

#if (DEBUG > 9)
			    fprintf(stderr, "WORD: %s\n", yytext);
#endif
			    yylval.string = (char *)strdup(yytext);
			    return (WORD);
			}

<INQUOTE>%[a-zA-Z.-]*	{

#if (DEBUG > 9)
			    fprintf(stderr, "ENTITY: %s\n", yytext);
#endif
			    yylval.string = (char *)strdup(&yytext[1]);
			    return (ENTITY);
			}
<INQUOTE>%[a-zA-Z.-]*;	{

#if (DEBUG > 9)
			    fprintf(stderr, "ENTITY: %s\n", yytext);
#endif
			    yylval.string = (char *)strdup(&yytext[1]);
			    yylval.string[strlen(yylval.string) - 1] = NULL;
			    return (ENTITY);
			}

<NORM>[\n \t]*		{
			}
.			{
			    fprintf(stderr, "%d: Unknown character: '%s'\n",
				    yylineno, yytext);
			}

%%

int
yygetlineno()
{
    return (yylineno);
}
